function [time, P] = GPM_Perm(C, P0)

[N,d] = size(P0);
n = N/d;

iter_max = 30;
tol = 1e-1;

time_start = tic;

% Initialization
P = P0;
P_last = zeros(N,d);
iter = 1;

while ( iter <= iter_max && norm(P - P_last) > tol )
    P_last = P;
    P = C*P;
    tic
    if (0)
        for i = 1:n
            P_cell{i} = P( ((i-1)*d*n/4)+1:(i*d*n/4) , : );
        end

        parfor i = 1:n
            P_cell{i} = munkres( -P_cell{i} );
        end

        for i = 1:n
            P( ((i-1)*d*n/4)+1:(i*d*n/4) , : ) = P_cell{i};
        end
    else
        for j = 1:n
            X = -P( (j-1)*d+1:j*d , : );
            %A1 = munkres( X );
            [assignment, ~] = assignmentoptimal(X);
            A = zeros(d);
            A((1:d)'+(assignment-1)*d) = 1;
            P( (j-1)*d+1:j*d , : ) = A;
        end
    end
    fprintf('GPM iter = %d,  n Munkres Total Time = %f\n', iter, toc);
    iter = iter + 1;
end

P = P*P(1:d,:)';

time = toc(time_start);